import axios, { type AxiosRequestConfig, type AxiosResponse } from 'axios';

// 创建 axios 实例
const instance = axios.create({
    baseURL: '/api', // 基础路径
    timeout: 10000, // 超时时间
});

// 请求队列
const requestQueue: Set<string> = new Set();

// 刷新 token 的标志和队列
let isRefreshing = false;
let refreshSubscribers: Array<(token: string) => void> = [];

// 通知刷新后的请求继续
const onRefreshed = (token: string) => {
    refreshSubscribers.forEach((callback) => callback(token));
    refreshSubscribers = [];
};

// 添加请求拦截器
instance.interceptors.request.use((config: any) => {
        // 防止重复请求
        const requestKey = `${config.method}-${config.url}`;
        if (requestQueue.has(requestKey)) {
            return Promise.reject(new Error('重复请求'));
        }
        requestQueue.add(requestKey);
        // 添加 token 到请求头
        const token = localStorage.getItem('token');
        if (token) {
            config.headers = {
                ...config.headers,
                Authorization: `Bearer ${token}`,
            };
        }
        return config;
    }, (error) => Promise.reject(error)
);

// 添加响应拦截器
instance.interceptors.response.use(
    (response: AxiosResponse) => {
        // 请求成功后移除请求队列中的请求
        const requestKey = `${response.config.method}-${response.config.url}`;
        requestQueue.delete(requestKey);
        return response;
    },
    async (error) => {
        const { config, response } = error;
        const originalRequest = config;

        // 如果返回 401，尝试刷新 token
        if (response?.status === 401 && !originalRequest._retry) {
            if (!isRefreshing) {
                isRefreshing = true;
                try {
                    const refreshToken = localStorage.getItem('refreshToken');
                    const { data } = await axios.post('/auth/refresh-token', { refreshToken });
                    localStorage.setItem('token', data.token);
                    isRefreshing = false;
                    onRefreshed(data.token);
                } catch (err) {
                    isRefreshing = false;
                    return Promise.reject(err);
                }
            }

            // 队列等待刷新完成
            return new Promise((resolve) => {
                refreshSubscribers.push((token: string) => {
                    originalRequest.headers.Authorization = `Bearer ${token}`;
                    resolve(instance(originalRequest));
                });
            });
        }

        // 其他错误直接返回
        return Promise.reject(error);
    }
);

// 封装 HTTP 方法
const http = {
    get<T = any>(url: string, config?: AxiosRequestConfig): Promise<T> {
        return instance.get(url, config).then((res) => res.data);
    },
    post<T = any>(url: string, data?: any, config?: AxiosRequestConfig): Promise<T> {
        return instance.post(url, data, config).then((res) => res.data);
    },
    put<T = any>(url: string, data?: any, config?: AxiosRequestConfig): Promise<T> {
        return instance.put(url, data, config).then((res) => res.data);
    },
    delete<T = any>(url: string, config?: AxiosRequestConfig): Promise<T> {
        return instance.delete(url, config).then((res) => res.data);
    },
};

export default http;